home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
v10n20.arc
/
DELM.ARC
/
DELM.ASM
next >
Wrap
Assembly Source File
|
1991-10-28
|
8KB
|
161 lines
PAGE 96,132
;**********************************************************************
; DELM.ASM Clipper UDF to delay n timer ticks
; Author..: Sal Ricciardi
;
; Use this file for program delays that are the same regardless
; of CPU type and speed. Relies on the BIOS timer tick count.
; Maximum delay is 65535 ticks (about 1 hr). Does not validate
; passed parameters.
;
; This version should work better under multitasking systems like
; Desqview or Microsoft Windows.
;
; Create with: TASM delm (Borland Turbo Assembler 2.5)
; TLINK delm
; EXE2BIN delm
; DEL DELM.OBJ
; DEL DELM.MAP
; DEL DELM.EXE
;
; Usage: (dBASE III Plus, FoxBASE+, dBASE IV)
;
; .LOAD DELM
; .ticks = 10 * 18.2 && for 10 seconds
; .CALL DELM WITH STR(ticks) && Don't forget the parameter
; .RELEASE DELM
;
;**********************************************************************
.MODEL SMALL
.CODE
Timerhigh EQU WORD PTR ds:[06eh]
Timerlow EQU WORD PTR ds:[06ch]
delay PROC FAR ;entry point
push ax ;save registers
push bx ;
push cx ;
push dx ;
push es ;
push ds ;
call asc2bin ;convert parameter to binary
mov cx,ax ;put it in cx
jcxz d999 ;skip if cx==0
mov ax,040h ;
mov ds,ax ;ds == 040h
;
; Get current timer count. Make sure we get both low and high at the same time.
;
cli ;interrupts off
mov ax,Timerlow ;get current tick count low
mov dx,Timerhigh ;get current tick count high
sti ;interrupts on
;
; Add the delay value to form the target timer count.
;
add ax,cx ;add ticks parameter to form
adc dx,0 ;target
;
cmp dx,018h ;q. target past midnight?
jb d500 ;a. no, handle normally
ja d400 ;a. yes, go handle special case
;
cmp ax,0B0h ;q. target past midnight?
jb d500 ;a. no, handle normally
;
; Target is past midnight. Adjust target and wait for midnight.
;
d400:
sub ax,0B0h ;subtract max to adjust the
sbb dx,018h ;target
d410: ;is past midnight
cmp Timerhigh,016h ;q. cross midnight yet?
jae d410 ;a. no,loop
;
; Delay until target time. This is where we attempt some level of insulation
; from multitasker interruption.
;
d500:
cmp Timerhigh,dx ;q. timerhigh reach the target?
je d510 ;a. yes, check timerlow
;
; Timerhigh could be greater than target if a multitasker had
; control for awhile, and we just returned
;
ja d999 ;a. greater than, we're done
;
; Could be less than by more than one if multitasker had control for awhile,
; and during that time midnight passed
;a. timerhigh is less than target
mov bx,dx ;get target in bx
sub bx,Timerhigh ;subtract current timerhigh
;
cmp bx,1 ;q. more than one less?
jne d999 ;a. yes, must be done
jmp d500 ;a. go check again
d510: ;
cmp Timerlow,ax ;q. timerlow less than target?
jb d510 ;a. yes, loop
;
; Clean up and return to caller
;
d999: ;
pop ds ;restore ds
pop es ;restore registers
pop dx ;
pop cx ;
pop bx ;
pop ax ;
ret ;return to caller
delay ENDP
;----------------------------------------------------------------------
; asc2bin Convert ascii decimal string to 16-bit unsigned binary
;
; Entry: DS:BX --> ascii string
; Exit: AX = 16-bit number
;
; Ignores leading blanks, then conversion stops at null or first
; non numeric.
;----------------------------------------------------------------------
asc2bin PROC
push bx ;Save bx and dx
push dx ;
mov si,bx ;Get offset in si
xor ax,ax ;Clear ax
xor bx,bx ;and bx
xor dx,dx ;and dx
a00001: ;
cmp BYTE PTR ds:[si],' ' ;q. leading blanks?
jne a00010 ;a. no.. move on
inc si ;a. yes.. ignore leading blanks
jmp a00001 ;(so we can use STR() function)
;
a00010: lodsb ;Get next ascii byte
or al,al ;q. is it zero?
jz a00090 ;a. yes .. finished
cmp al,'9' ;q. is > 9?
ja a00090 ;a. yes .. finished
cmp al,'0' ;q. is it < 0?
jb a00090 ;a. yes .. finished
a00020: ;Multiply current answer by 10
mov dx,bx ;Save in dx
shl bx,1 ;* 2
shl bx,1 ;* 4
add bx,dx ;* 5
shl bx,1 ;* 10
and ax,0fh ;Mask off ascii
add bx,ax ;Add to result
jmp a00010 ;go get next byte
a00090: ;
mov ax,bx ;Put result in ax
pop dx ;Restore registers
pop bx ;
ret ;return to caller
asc2bin ENDP
END